/*
* Copyright (C) 2020 ~ 2024 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/

#include "MkStateGridB/MkStateGridB.h"
#include <MkUtil/MkLog.h>
#include "MkEvent/MkEventPool.h"
#include <signal.h>
#include "MkEvent/MkTimer.h"
CMkTimer     g_Timer;
MkString    g_AlarmSubId;
MkString    g_StateSubId;
MkString    g_RegisterId;
Uint32 MessageReqestCallback(CMkStateGridB *pSvr, const CMkStateGridBRequestBase* pRequest, const MkStateGridBResponseCallback& ResCb)
{
    switch (pRequest->GetMsgType()) {
    case MkStateGridBMedia:
    {
        const CMkStateGridBMediaRequest* pReq = dynamic_cast<const CMkStateGridBMediaRequest*>(pRequest);
        if (pReq)
        {
            CMkStateGridBMediaResponse Res(pReq->GetRouterId(), pReq->GetDstId(), "111", "192.168.0.13",nullptr);
            ResCb(NoneError, &Res);
        }
    }
    break;
    case MkStateGridBMediaShutDown:
        MkInfoLog("recv media shut down\n");
        ResCb(NoneError, nullptr);
        break;
    case MkStateGridBPtzControl:
        MkInfoLog("recv ptz control\n");
        ResCb(NoneError, nullptr);
        break;
    case MkStateGridBSubscribe:
    {
    }
        ResCb(NoneError, nullptr);
        MkInfoLog("recv alarm subscribe\n");
        pSvr->AlarmNotify(g_AlarmSubId, "State", "Code", "Name", 1, NowMkTime,NowMkTime,nullptr);
        break;
    default:
        break;
    }
    return NoneError;
}

Uint32 RegisterServer(CMkStateGridB* pSvr,const MkString& ServerId, Uint32 Expires,const MkMapString& AuthorizationParam)
{
    if (AuthorizationParam.empty())
    {
        return pSvr->RegisterServer(ServerId, Expires, [pSvr, ServerId, Expires](Uint32 ErrorCode, const CMkStateGridBResponseBase* pResponse) {
            const CMkStateGridBRegisterResponse* pRes = dynamic_cast<const CMkStateGridBRegisterResponse*>(pResponse);
            if (pRes
                &&NoneError == ErrorCode) {
                if (MkSipStatusUnauthorized == pRes->GetStatusCode()) {
                    MkMapString MapParam;
                    MapParam["username"] = "\"123\"";
                    MapParam["realm"] = "\"" + pRes->GetUpRealm() + "\"";
                    MapParam["nonce"] = "\"" + pRes->GetUpNonce();
                    MapParam["uri"] = "\"sip:xxx@1122\"";
                    MapParam["response"] = "\"123\"";
                    MapParam["algorithm"] = pRes->GetUpAlgorithm();
                    g_RegisterId = pRes->GetRegisterId();
                    RegisterServer(pSvr, ServerId, Expires, MapParam);
                } else if (MkSipStatusOK == pRes->GetStatusCode()) {
                    MkDebugLog("register server success\n");
                } else {
                    ErrorCode = InvalidParams;
                }
            }
        });
    } else {
        return pSvr->RegisterServerWithRegisterId(g_RegisterId, Expires, AuthorizationParam, [](Uint32 ErrorCode, const CMkStateGridBResponseBase* pResponse)
        {
            MkDebugLog("register server error:%d\n", ErrorCode);
        });
    }
}

Uint32 UnRegisterServer(CMkStateGridB* pSvr, const MkString& RegId, const MkMapString& AuthorizationParam)
{
    return pSvr->RegisterServerWithRegisterId(RegId,0,AuthorizationParam, [pSvr,RegId](Uint32 ErrorCode, const CMkStateGridBResponseBase* pResponse) {
        const CMkStateGridBRegisterResponse* pRes = dynamic_cast<const CMkStateGridBRegisterResponse*>(pResponse);
        if (pRes
            &&NoneError == ErrorCode) {
            if (MkSipStatusUnauthorized == pRes->GetStatusCode()) {
                MkMapString MapParam;
                MapParam["username"] = "\"123\"";
                MapParam["realm"] = "\"" + pRes->GetUpRealm() + "\"";
                MapParam["nonce"] = "\"" + pRes->GetUpNonce();
                MapParam["uri"] = "\"sip:xxx@1122\"";
                MapParam["response"] = "\"123\"";
                MapParam["algorithm"] = pRes->GetUpAlgorithm();
                UnRegisterServer(pSvr, RegId,  MapParam);
            } else if (MkSipStatusOK == pRes->GetStatusCode()) {
                MkDebugLog("register server success\n");
            } else {
                ErrorCode = InvalidParams;
            }
        }
    });
}


int main(int argc, char ** argv)
{

#ifdef _WIN32
    WSADATA WSAData;
    WSAStartup(0x101, &WSAData);
#else
    signal(SIGPIPE, SIG_IGN);  //ignore sigpipe
#endif
    MkLogChangeLevel(LOG_DEBUG);
    CMkEventPool Pool;
    g_Timer.StartTimerThread();

    Pool.Start();
    CMkStateGridB LowSvr(&Pool, &g_Timer);
    CMkStateGridB* pSvr = &LowSvr;
    MkStateGridBStartParam Param;
    Param.LocalHost = "0.0.0.0";
    Param.LocalPort = 5080;
    Param.MappingHost = "";
    Param.MappingPort = 0;
    Param.RegisterExpires = 3600;
    Param.SubscribeExpires = 3600;
    Param.SipId = "34020000001110000001";
    Param.SipRealm = "3402000000";
    LowSvr.Start(Param, [pSvr](const CMkStateGridBRequestBase* pRequest, const MkStateGridBResponseCallback& ResCb) {
        return MessageReqestCallback(pSvr, pRequest, ResCb);
    });

    signal(SIGINT, [](int sig) {
        if (SIGINT == sig) {
            g_Timer.LoopBreak();
        }
    });// set exit  signal
    char GetC;
    while (GetC = getchar()) {
        BOOL bQuit = FALSE;
        MkDebugLog("get char:%c\n", GetC);
        switch (GetC) {
        case '1':
            LowSvr.AlarmNotify(g_AlarmSubId, "State", "Code", "Name", 1, NowMkTime, NowMkTime, [](Uint32 ErrorCode, const CMkStateGridBResponseBase* pResponse) {
                MkDebugLog("alarm notify return:%d\n", ErrorCode);
            });
            break;
        case '2':
            LowSvr.StateNotify(g_StateSubId, "State", "Code", "Name", 1, [](Uint32 ErrorCode, const CMkStateGridBResponseBase* pResponse) {
                MkDebugLog("state notify return:%d\n", ErrorCode);
            });
            break;
        case '3':
            LowSvr.ByeStream("666", [](Uint32 ErrorCode, const CMkStateGridBResponseBase* pResponse) {
                MkDebugLog("stop real play return:%d\n", ErrorCode);
            });
            break;
        case '4':
            break;
        case '5':
            LowSvr.AddRouter("181210000000000000", "1812100000", "192.168.0.13", 5060, FALSE);
            RegisterServer(pSvr, "181210000000000000", 3600,MkMapString());
            break;
        case '6':
            UnRegisterServer(pSvr, g_RegisterId, MkMapString());
            break;
        case '7':
        {
            MkMapStateGridBResourse MapResource;
            MkStateGridBResourseItem Item;
            Item.Code = "111";
            Item.Status = TRUE;
            Item.Name = "啊啊啊";
            Item.DecodeTag = 100;
            Item.Longitude = 1.0f;
            Item.Latitude = 1.0f;
            Item.SubNum = 1;
            MapResource[Item.Code] = Item;
            LowSvr.ResourcePush("181210000000000000", "181210000000000000", "1111", MapResource, [](Uint32 ErrorCode, const CMkStateGridBResponseBase* pResponse) {
                MkDebugLog("resource push return:%d\n", ErrorCode);
            });
        }
            break;
        case 'q':
            bQuit = TRUE;
            break;
        default:
            break;
        }
        if (bQuit) {
            break;
        }
    }
    g_Timer.StopTimerThread();
    Pool.Stop();
    LowSvr.Stop();
#ifdef _WIN32
    WSACleanup();
#endif
    printf("end\n");
    return 0;
}


